package view;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.*;

import javax.swing.*;

import model.Hand;
import model.Player;
import model.Rank;
import model.Suit;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

public class GameView extends View implements ActionListener, Observer  {

	final static boolean shouldFill = true;

	private int numberOfPlayers;

	private int activePlayer;

	private Timer hitTimerOne;
	private Timer hitTimerTwo;

	private ArrayList<Card> playerCards, dealerCards;
	private JLabel[] avatars;

	private JButton hitButton, standButton;
	private JLabel cashLabel, betLabel, playerPointsLabel;

	private int[] numberOfCards;

	private final int cardPosX = 900;
	private final int cardPosY = 50;


	/**
	 * 
	 */
	private static final long serialVersionUID = -1630919905574799437L;

	public GameView(int numberOfPlayers_, int[] playerAvatars) {

		super("bg2.jpg");

		numberOfPlayers = numberOfPlayers_;

		numberOfCards = new int[numberOfPlayers];

		avatars = new JLabel[numberOfPlayers];

		for(int i = 0; i < numberOfPlayers; i++) {

			avatars[i] = new JLabel();

			avatars[i].setLocation(300, 480);
			avatars[i].setSize(115, 117);

			avatars[i].setIcon(new ImageIcon("img/avatars/" + playerAvatars[i] + ".png"));

		}


		playerCards = new ArrayList<Card>();
		dealerCards = new ArrayList<Card>();

		hitButton = new JButton("Hit");
		standButton = new JButton("Stand");

		hitButton.setSize(70, 20);
		standButton.setSize(70, 20);

		hitButton.setLocation(470, 500);
		standButton.setLocation(555, 500);

		cashLabel = new JLabel("1500");
		cashLabel.setForeground(Color.white);
		cashLabel.setFont(new Font("Calibri", Font.BOLD, 35));

		betLabel = new JLabel("0");
		betLabel.setForeground(Color.white);
		betLabel.setFont(new Font("Calibri", Font.BOLD, 35));

		playerPointsLabel = new JLabel("0");
		playerPointsLabel.setForeground(Color.white);
		playerPointsLabel.setFont(new Font("Calibri", Font.BOLD, 35));

		playerPointsLabel.setSize(120, 60);
		playerPointsLabel.setLocation(420, 450);

		cashLabel.setText("");

		cashLabel.setSize(120, 60);
		cashLabel.setLocation(50, 75);

		betLabel.setSize(120, 60);
		betLabel.setLocation(50, 135);

		this.setLayout(null);
		addComponents();

	}

	public void setPlayerPoints(int points) {

		playerPointsLabel.setText(Integer.toString(points));

	}

	public void addHitListener(ActionListener l) {

		hitButton.addActionListener(l);

	}

	public void addStandListener(ActionListener l) {

		standButton.addActionListener(l);

	}

	public void switchPlayer() {

		cashLabel.setText("");
		betLabel.setText("");

	}

	public int getActivePlayer() {

		return activePlayer;

	}

	public void setActivePlayer(int activePlayer_) {

		activePlayer = activePlayer_;

	}

	public void addComponents() {

		add(avatars[0]); //Adds the first players avatar
		add(hitButton);
		add(standButton);
		add(cashLabel);
		add(betLabel);
		add(playerPointsLabel);

	}

	public void setNumberOfCards(int playerIndex, int numberOfCards_) {

		numberOfCards[playerIndex] = numberOfCards_;

	}

	public void drawHand(int type, Hand hand) { //type 0 = player, type 1 = dealer

		if(type == 0) {

			for(int i = 0; i < hand.getNoOfCards(); i++) {

				playerCards.add(new Card(hand.getCard(i).getRank(), hand.getCard(i).getSuit(), cardPosX, cardPosY));

				playerCards.get(i).setShowCard(true);

				add(playerCards.get(i));

				initialHitAnimation(type, i);

			}

		}
		else {

			for(int i = 0; i < hand.getNoOfCards(); i++) {

				dealerCards.add(new Card(hand.getCard(i).getRank(), hand.getCard(i).getSuit(), cardPosX, cardPosY));

				dealerCards.get(i).setShowCard(true);

				add(dealerCards.get(i));

				initialHitAnimation(type, i);

			}

		}

	}

	public void updateDealerHand(Hand hand) {

		for(int i = 1; i < hand.getNoOfCards(); i++) {

			dealerCards.add(new Card(hand.getCard(i).getRank(), hand.getCard(i).getSuit(), cardPosX, cardPosY));

			dealerCards.get(i).setShowCard(true);

			add(dealerCards.get(i));

			hitAnimation(1, i);

		}

	}

	public void Hit(Hand hand) {

		int latestAddedCardIndex = hand.getNoOfCards() - 1;

		playerCards.add(new Card(hand.getCard(latestAddedCardIndex).getRank(), hand.getCard(latestAddedCardIndex).getSuit(), cardPosX, cardPosY));

		playerCards.get(latestAddedCardIndex).setShowCard(true);

		add(playerCards.get(latestAddedCardIndex));

		hitAnimation(0, latestAddedCardIndex);

	}

	public void initialHitAnimation(final int type, final int cardIndex) { //Type 0 = player, type 1 = dealer

		hitTimerOne = new Timer(10, new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent event) {

				if(type == 0) {
					playerHitAnimation(true, playerCards.get(cardIndex), cardIndex);
				}
				else {
					dealerHitAnimation(true, dealerCards.get(cardIndex), cardIndex);
				}

			}

		});

		hitTimerOne.start();

	}

	public void hitAnimation(final int type, final int cardIndex) { //Type 0 = player, type 1 = dealer

		hitTimerTwo = new Timer(10, new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent event) {

				if(type == 0) {
					playerHitAnimation(false, playerCards.get(cardIndex), cardIndex);
				}
				else {
					dealerHitAnimation(false, dealerCards.get(cardIndex), cardIndex);
				}

			}

		});

		hitTimerTwo.start();

	}

	public void playerHitAnimation(boolean initial, Card card, int cardIndex) {

		int x, y;

		x = card.getX();
		y = card.getY();

		if(cardIndex == 0) {

			x = x - 6;

		}
		else {

			x = x - (6 - cardIndex);

		}

		y = y + 5;

		if(y == 405) {
			if(initial)
				hitTimerOne.stop();
			else
				hitTimerTwo.stop();

		}
		else {

			card.setLocation(x, y);

		}

		System.out.println("Running playerHitAnimation..");

		repaint();

	}

	public void dealerHitAnimation(boolean initial, Card card, int cardIndex) {

		int x, y;

		x = card.getX();
		y = card.getY();

		x = x - 5;
		
		card.setLocation(x, y);

	/*	if(x == 100) {

			if(initial)
				hitTimerOne.stop();
			else
				hitTimerTwo.stop();

		}
		else {

			card.setLocation(x, y);

		} */
		
		System.out.println("Running dealerHitAnimation..");

		repaint();

	}

	@Override
	public void update(Observable obj, Object arg) {

		if(arg instanceof Player) {
			
			Player player = (Player) arg;
				
				setPlayerPoints(player.getPoints());
				//setPlayerBet, setPlayerCash osv..

		}
		else if(arg instanceof Integer) {

			int checkPoints = (Integer) arg;

			if(checkPoints == 1) {

				JOptionPane.showMessageDialog(this, "Player got 21 points!");

			}
			else if(checkPoints == 2) {

				JOptionPane.showMessageDialog(this, "Player busted!");

			}
			else if(checkPoints == 3) {

				JOptionPane.showMessageDialog(this, "Dealer got 21 points!");

			}
			else if(checkPoints == 4) {

				JOptionPane.showMessageDialog(this, "Dealer busted!");

			}
			else if(checkPoints == 5) {

				JOptionPane.showMessageDialog(this, "Push! Nobody wins or loses");

			}
			else if(checkPoints == 6) {

				JOptionPane.showMessageDialog(this, "Player wins!");

			}
			else if(checkPoints == 7) {

				JOptionPane.showMessageDialog(this, "Dealer wins!");

			}

		}

	}


}
